/*
	Работа с АЦП
*/
#include <RTL.h>
#include <LPC17xx.h>
#include <string.h>
#include "timer.h"
#include "adc.h"

volatile U32 adcValues[4];
volatile U8 adcChannel=0;
volatile U8 adcBusy=0;
volatile U16 adcCount=0; //Сколько циклов оцифровки уже произведено

//Текущее среднее значение
AdcT adcAverage;

//Время когда последний раз оцифровывали
U32 adcStartTime=0;

/*
	Настройка АЦП
*/
void adc_init(void)
{
	//Подаем питание на АЦП
  LPC_SC->PCONP |= (1 << 12);

	//Входы АЦП
	//P0.23~26, A0.0~3, function 01
  LPC_PINCON->PINSEL1 &= ~0x003FC000;	
  LPC_PINCON->PINSEL1 |= 0x00154000;
  
  //No pull-up no pull-down (function 10) on these ADC pins.
  LPC_PINCON->PINMODE1 &= ~0x003FC000;
  LPC_PINCON->PINMODE1 |= 0x002A8000;

	//По умолчанию в LPC_SC->PCLKSEL0 стоит  SystemFreq/4
	
	//Разрещаем прерывания
	NVIC_EnableIRQ(ADC_IRQn);
	LPC_ADC2->INTEN = 0x10F;		
}

/*
	Старт процесса оцифровки
*/
void adc_start(void)
{
	//printf("adc start\r\n");
	adcBusy=1;
	adc_start_channel(adcChannel=0);
}
/*
	Старт оцифровки на нужном канале
*/
void adc_start_channel(U8 channel)
{
		LPC_ADC2->CR = ( 0x01 << channel ) |  // SEL=1,select channel 0~7 on ADC0 
		( 24 << 8 ) |  // CLKDIV = Fpclk / ADC_Clk - 1  
		( 0 << 16 ) | 		/* BURST = 0, no BURST, software controlled */
		( 1 << 21 ) |  		/* PDN = 1, normal operation */
		( 1 << 24 ) |  		/* START = 1 A/D conversion starts */
		( 0 << 27 );		/* EDGE = 0 (CAP/MAT singal falling,trigger A/D conversion) */ 
}

/*
	Остановка АЦП
*/
void adc_stop()
{
	LPC_ADC2->CR &= ~((0x7<<24)|(0x1<<16));
}

/*
	Прерывание - окончали оцифровывать
*/
void ADC_IRQHandler  (void) __irq
{
	uint32_t regVal;
	regVal = LPC_ADC2->STAT;
	
	//Считываем значение и накапливаем его
	adcValues[adcChannel]+=( LPC_ADC2->DR[adcChannel] >> 4 ) & 0xFFF;
	
	//Прошлись по всем каналам
	if (++adcChannel>=4)
	{	
		adcChannel=0;
		adc_stop();
		adcBusy=0;
		adcCount++;
		//printf("Count:%d Values:%08x %08x %08x %08x\r\n",adcCount,adcValues[0],adcValues[1],adcValues[2],adcValues[3]);
	}
	else
	{
		//printf("adc channel: %d\r\n",adcChannel);
		adc_start_channel(adcChannel);
	}
}

/*
	Запускаем процесс оцифровки каждые 20мс
*/
void adc_prc(void)
{
	//Что-то давно мы не оцифровывали!!
	if (SystemTick-adcStartTime>=ADC_INTERVAL)
	{
		//А вдруг заняты - что маловероятно!
		if(!adcBusy)
			adc_start();
	}
}

/*
	Запрашиваем среднее значение
*/
AdcT adc_get_average(void)
{
	//Надо подождать - вдруг АЦП занято - это не долго!
	while(adcBusy)
		;
	
	adcAverage.adc1 = (U16)(adcValues[0]/adcCount);
	adcAverage.adc2 = (U16)(adcValues[1]/adcCount);
	adcAverage.adc3 = (U16)(adcValues[2]/adcCount);
	adcAverage.adc4 = (U16)(adcValues[3]/adcCount);
	
	//А теперь все обнуляем
	memset((U8 *)adcValues,0x00,sizeof(adcValues));
	adcCount=0;
	
	return adcAverage;
}


